B = [[0] * 3] * 3
print(B) # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

# 期望给中间的元素换一个值
B[1][1] = 100
# 结果影响到了3个元素，为什么？
# 我们知道原因是内部嵌套的列表，不是三个独立的列表，而是同一个列表的三次引用而已
print(B) # [[0, 100, 0], [0, 100, 0], [0, 100, 0]]

A = [0] * 3
print(A) # [0, 0, 0]
A[1] = 100
# 因为A不是嵌套列表，所以不存在引用的问题
print(A) # [0, 100, 0]

A = [0] * 3
for i in range(3) : 
    # 同步每次循环，创建一个列表赋值给A中的每个元素，就创建了一个嵌套列表
    A[i] = [0] * 3
print(A) # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
A[1][1] = 100
# 只会修改一个元素
print(A) # [[0, 0, 0], [0, 100, 0], [0, 0, 0]]

# 由上可知，创建一个嵌套列表太麻烦了，有没有更好的办法？

# 使用列表腿导式
S = [[0] * 3 for i in range(3)]
print(S) # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
S[1][1] = 100
# 只会修改一个元素
print(S) # [[0, 0, 0], [0, 100, 0], [0, 0, 0]]


# 高阶推导式 expression for target in iterable if condition
# 执行顺序:
# 1.for target in iterable
# 2.if condition
# 3.expression
even = [i for i in range(10) if i % 2 == 0]
print(even) # [0, 2, 4, 6, 8]

even = [i + 1 for i in range(10) if i % 2 == 0]
print(even) # [1, 3, 5, 7, 9] 说明在循环过程中，只有满足条件的i才会去执行左侧的表达式

words = ["Great","FishC","Brilliant","Excellent","Fantastic"]
# 使用列表推导式筛选出 F 开头的单词
f_words = [w for w in words if w[0] == 'F'] # 字符串 FishC 的 FishC[0] 就是 F
print(f_words) # ['FishC', 'Fantastic']
f_words = [w for w in words if w.startswith("F")]
print(f_words) # ['FishC', 'Fantastic']
print("FishC"[0]) # F


# 嵌套的列表推导式
# expression for target1 in iterable1
#                target2 in iterable2
#                ...
#                targetN in iterableN

# 将二维列表降级为一维列表
matrix = [
    [1,2,3],
    [4,5,6],
    [7,8,9]
]

# TODO 没有理解
flatten = [
        col
        for 
        row in matrix 
        for 
        col in row
        ]
print(flatten) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 上面的嵌套列表等价下面的循环
flatten = []
for row in matrix:
    for col in row :
        flatten.append(col)
print(flatten) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 结论：外层的循环放在嵌套推导式的前面，内部的循环放在嵌套推导式的后面

t = [x + y for x in "fishc" for y in "FISHC"]
# x 从外层循环取，y从哪层循环取
print(len(t)) # 25 其实就是笛卡尔乘积
print(t) # 'fF', 'fI', 'fS', 'fH', 'fC', 'iF', 'iI', 'iS', 'iH', 'iC', 'sF', 'sI', 'sS', 'sH', 'sC', 'hF', 'hI', 'hS', 'hH', 'hC', 'cF', 'cI', 'cS', 'cH', 'cC']

# 下面是使用循环的

# 如果变量是临时的或者无关紧要的，那么就可以用 _ 做变量名
_ = []
for x in "fishc":
    for y in "FISHC":
        _.append(x + y)
print(_) # 'fF', 'fI', 'fS', 'fH', 'fC', 'iF', 'iI', 'iS', 'iH', 'iC', 'sF', 'sI', 'sS', 'sH', 'sC', 'hF', 'hI', 'hS', 'hH', 'hC', 'cF', 'cI', 'cS', 'cH', 'cC']



# 嵌套的列表推导式-终极版
# expression for target1 in iterable1 if condition1
#                target2 in iterable2 if condition2
#                ...
#                targetN in iterableN if conditionN

# 方法A
# x 能被2整除，y 能被3整除
_ = [[x,y] for x in range(10) if x % 2 == 0 for y in range(10) if y % 3 == 0]
print(len(_)) # 20
print(_) # [[0, 0], [0, 3], [0, 6], [0, 9], [2, 0], [2, 3], [2, 6], [2, 9], [4, 0], [4, 3], [4, 6], [4, 9], [6, 0], [6, 3], [6, 6], [6, 9], [8, 0], [8, 3], [8, 6], [8, 9]]


# 方法B
_ = []
for x in range(10) :
    for y in range(10) :
        if(x % 2 == 0 and y % 3 == 0) :
            _.append([x, y])
print(len(_)) # 20
print(_) # [[0, 0], [0, 3], [0, 6], [0, 9], [2, 0], [2, 3], [2, 6], [2, 9], [4, 0], [4, 3], [4, 6], [4, 9], [6, 0], [6, 3], [6, 6], [6, 9], [8, 0], [8, 3], [8, 6], [8, 9]]

# 方法C
_ = []
for x in range(10) :
    if x % 2 == 0:
        for y in range(10) :
            if y % 3 == 0:
                _.append([x, y])
print(len(_)) # 20
print(_) # [[0, 0], [0, 3], [0, 6], [0, 9], [2, 0], [2, 3], [2, 6], [2, 9], [4, 0], [4, 3], [4, 6], [4, 9], [6, 0], [6, 3], [6, 6], [6, 9], [8, 0], [8, 3], [8, 6], [8, 9]]


# 但是，KISS原则：Keep Is Simple & Stupid
